//
//  QZoneEngine.m
//  PUDemo
//
//  Created by JK.Peng on 13-2-22.
//  Copyright (c) 2013年 njut. All rights reserved.
//

#import "QZoneEngine.h"

#define kQZoneTokenKey           @"access_token"

#define kOFKeychainOauth2QZoneOpenId  @"kOFKeychainOauth2QZoneOpenId"

@interface QZoneEngine (){
    OFRequest    *_openIdRequset;
    
    //分享到QQ空间时，分享图片时用
    NSString     *_shareComment;
    NSString     *_shareTitle;
    NSString     *_shareSummary;
    NSString     *_linkURL;
    
    NSString     *_imageUrl;
}

@end

@implementation QZoneEngine

@synthesize openId = _openId;

- (id)initWithAppId:(NSString *)theAppId appKey:(NSString *)theAppKey;
{
    self = [super initWithAppKey:theAppId appSecret:theAppKey type:kOFTypeQZone];
    if (self) {
    }
    return self;
}

- (void)dealloc
{
    [_openId release], _openId = nil;
    [_openIdRequset disconnect];
    [_openIdRequset release], _openIdRequset = nil;
    [_shareTitle release], _shareTitle = nil;
    [_shareComment release], _shareComment = nil;
    [_shareSummary release], _shareSummary = nil;
    [_linkURL release], _linkURL = nil;
    [_imageUrl release],_imageUrl = nil;
    [super dealloc];
}

- (void)requestOpenId
{
    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:self.accessToken,@"access_token", nil];
    _openIdRequset = [OFRequest requestWithURL:@"https://graph.qq.com/oauth2.0/me"
                                    httpMethod:@"GET"
                                        params:params
                                  postDataType:kOFRequestPostDataTypeNone
                              httpHeaderFields:nil
                                      delegate:self];
    [_openIdRequset connect];
}

#pragma mark - WBAuthorizeOauth2DataSource
/*
 第一步：请求code
 请求方法：
 GET
 请求地址：https://graph.z.qq.com/moc2/authorize
 */
- (NSString *)authorizeOauth2AuthorizeURL:(OFAuthorizeOauth2 *)authorize
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    _appKey, @"client_id",
                                    QZONE_REDIRECT_URI, @"redirect_uri",
                                    @"code", @"response_type",
                                    @"get_user_info,add_share,upload_pic", @"scope",
                                    @"mobile",@"display",
                                    nil];
    
    return [OFRequest serializeURL:@"https://graph.qq.com/oauth2.0/authorize"
                            params:params
                        httpMethod:@"GET"];
}
/*
 第二步：请求accesstoken
 请求地址：https://graph.z.qq.com/moc2/token
 */
- (OFRequest *)authorizeOauth2WBRequestForAccessToken:(OFAuthorizeOauth2 *)authorize authorizeCode:(NSString *)code
{
    
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    _appKey, @"client_id",
                                    _appSecret, @"client_secret",
                                    QZONE_REDIRECT_URI, @"redirect_uri",
                                    @"authorization_code", @"grant_type",
                                    code,@"code",
                                    @"1",@"state",
                                    nil];
    
    return [self generateRequestWithUrl:@"https://graph.qq.com/oauth2.0/token"
                             httpMethod:@"GET"
                                 params:params
                           postDataType:kOFRequestPostDataTypeNone
                       httpHeaderFields:nil
                               delegate:authorize];
}

#pragma mark - OFAuthorizeOauth2Delegate
- (OFAuthorizeParseResult *)authorizeOauth2:(OFAuthorizeOauth2 *)authorize parseAuthorizeCode:(NSString *)string
{
    OFAuthorizeParseResult * result = [[[OFAuthorizeParseResult alloc] init] autorelease];
    NSArray * pairsAry = [string componentsSeparatedByString:@"&"];
    for (NSString * pairString in pairsAry) {
        NSArray * pair = [pairString componentsSeparatedByString:@"="];
        if ([pair count] == 2) {
            if ([[pair objectAtIndex:0] isEqualToString:@"code"]) {
                result.authorizeCode = [pair objectAtIndex:1];
            } else if ([[pair objectAtIndex:0] isEqualToString:@"error_code"]) {
                result.authorizeCode = [pair objectAtIndex:1];
                result.authorizeErrorCode = YES;
            }
        }
    }
    if (result.authorizeCode) {
        return result;
    } else {
        return nil;
    }
}

- (BOOL)authorizeOauth2:(OFAuthorizeOauth2 *)authorize parseAccessToken:(NSString *)string
{
    
    NSMutableDictionary   *dic = [NSMutableDictionary dictionaryWithCapacity:0];
    NSArray * pairsAry = [string componentsSeparatedByString:@"&"];
    
    for (NSString  *pairString in pairsAry) {
        NSArray * pair = [pairString componentsSeparatedByString:@"="];
        if ([pair count] == 2) {
            [dic setObject:[pair objectAtIndex:1] forKey:[pair objectAtIndex:0]];
        }
    }
    
    self.accessToken = [dic objectForKey:@"access_token"];
    unsigned long expires = (unsigned long)[[dic objectForKey:@"expires_in"] longLongValue];
    self.expireTime = expires+[[NSDate date] timeIntervalSince1970];
    
    //若token请求成功，则请求openId
    if (_accessToken) {
        [self requestOpenId];
    }
    
    if (self.accessToken && self.expireTime > 0) {
        return YES;
    }
    
    return NO;
}


#pragma mark - Overwrite
- (BOOL)isLoggedIn
{
    return ([super isLoggedIn] && _openId);
}

- (void)saveAuthorizeData
{
    [[NSUserDefaults standardUserDefaults] setObject:_openId forKey:kOFKeychainOauth2QZoneOpenId];
    [super saveAuthorizeData];
}

- (void)readAuthorizeData
{
    self.openId = [[NSUserDefaults standardUserDefaults] objectForKey:kOFKeychainOauth2QZoneOpenId];
    [super readAuthorizeData];
}

- (void)deleteAuthorizeData
{
    self.openId = nil;
    [super deleteAuthorizeData];
}

#pragma mark - Private
- (OFRequest *)generateRequestWithUrl:(NSString *)url
                           httpMethod:(NSString *)httpMethod
                               params:(NSMutableDictionary *)params
                         postDataType:(OFRequestPostDataType)postDataType
                     httpHeaderFields:(NSDictionary *)httpHeaderFields
                             delegate:(id<OFRequestDelegate>)aDelegate
{
    return [self generateRequestWithUrl:url
                             httpMethod:httpMethod
                                 params:params
                           postDataType:postDataType
                       httpHeaderFields:httpHeaderFields
                               tokenKey:kQZoneTokenKey
                               delegate:aDelegate];
}

- (NSMutableDictionary *)commonParams
{
    NSMutableDictionary  *params = [NSMutableDictionary dictionaryWithCapacity:0];
    if (_appKey) {
        [params setObject:_appKey forKey:@"oauth_consumer_key"];
    }
    
    if (_accessToken) {
        [params setObject:self.accessToken forKey:@"access_token"];
    }
    
    if (_openId) {
        [params setObject:_openId forKey:@"openid"];
        
    }
    [params setObject:@"json" forKey:@"format"];
    return params;
}

- (NSMutableDictionary *)commonParamsForV3
{
    NSMutableDictionary  *params = [NSMutableDictionary dictionaryWithCapacity:0];
    [params setObject:QZONEAPPID forKey:@"appid"];
    [params setObject:QZONEAPPKEY forKey:@"openkey"];
    
    [params setObject:@"qzone" forKey:@"pf"];
    [params setObject:@"json" forKey:@"format"];
    
    return params;
}

- (NSString *)generateSignatureBaseWithUrl:(NSURL *)aUrl
                                httpMethod:(NSString *)aHttpMethod
                                parameters:(NSDictionary *)aParameters
{
    NSMutableArray * paramsAry = [NSMutableArray arrayWithCapacity:0];
    
    //将除“sig”外的所有参数按key进行字典升序排列，排列结果为：appid，openid，openkey，pf
    [aParameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if ([obj isKindOfClass:[NSString class]]) {
            [paramsAry addObject:[NSString stringWithFormat:@"%@=%@",
                                  (NSString *)key,
                                  [(NSString *)obj URLEncodedString]]];
        }
    }];
    [paramsAry sortUsingSelector:@selector(compare:)];
    
    //将第2步中排序后的参数(key=value)用&拼接起来：
    NSString * paramsString = [paramsAry componentsJoinedByString:@"&"];
    
    NSString * urlWithoutQuery = nil;
    
    if ([aUrl port]) {
		urlWithoutQuery = [NSString stringWithFormat:@"%@:%@//%@%@", [aUrl scheme], [aUrl port], [aUrl host], [aUrl path]];
	} else {
		urlWithoutQuery = [NSString stringWithFormat:@"%@://%@%@", [aUrl scheme], [aUrl host], [aUrl path]];
	}
	
    //将HTTP请求方式，第1步以及第3步中的到的字符串用&拼接起来，得到源串：
    NSString * signatureBase = [NSString stringWithFormat:@"%@&%@&%@",
                                aHttpMethod,
                                [urlWithoutQuery URLEncodedString],
                                [paramsString URLEncodedString]];
    
    //构造密钥   得到密钥的方式：在应用的appkey末尾加上一个字节的“&”，即appkey&
    NSString * signatureKey = [NSString stringWithFormat:@"%@&",
                               self.appSecret?[self.appSecret URLEncodedString]:@""];
    
    //生成签名值
	NSData *signature = [signatureBase HMACSHA1EncodedDataWithKey:signatureKey];
    
    //将加密后的字符串经过Base64编码
	NSString *base64Signature = [signature base64EncodedString];
	return base64Signature;
}

#pragma mark - QQ空间 相关API
- (void)requestOtherUserProfile:(NSString *)uId
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithDictionary:[self commonParamsForV3]];
    if (_openId) {
        [params setObject:self.openId forKey:@"openid"];
    }
    
    if (uId) {
        [params setObject:uId forKey:@"fopenids"];
    }
    
    NSString  *urlStr = @"http://openapi.tencentyun.com/v3/user/get_multi_info";
    NSString * signature = [self generateSignatureBaseWithUrl:[NSURL URLWithString:urlStr]
                                                   httpMethod:@"GET"
                                                   parameters:params];
    [params setObject:signature forKey:@"sig"];
    
    OFRequest  *rpofileRe = [OFRequest requestWithURL:urlStr
                                           httpMethod:@"GET"
                                               params:params
                                         postDataType:kOFRequestPostDataTypeNone
                                     httpHeaderFields:nil
                                             delegate:self];
	if (rpofileRe) {
        [_requestAry addObject:rpofileRe];
        [rpofileRe connect];
    } else {
        [self delegateEngineRequestDidFailWithError:nil];
    }
}

//- (void)requestUserProfile
//{
//    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithDictionary:[self commonParamsForV3]];
//    if (_openId) {
//        [params setObject:self.openId forKey:@"openid"];
//    }
//
//    NSString  *urlStr = @"http://openapi.tencentyun.com/v3/user/get_info";
//    NSString * signature = [self generateSignatureBaseWithUrl:[NSURL URLWithString:urlStr]
//                                                   httpMethod:@"GET"
//                                                   parameters:params];
//    [params setObject:signature forKey:@"sig"];
//
//    WBRequest  *rpofileRe = [WBRequest requestWithURL:urlStr
//                                           httpMethod:@"GET"
//                                               params:params
//                                         postDataType:kWBRequestPostDataTypeNone
//                                     httpHeaderFields:nil
//                                             delegate:self];
//	if (rpofileRe) {
//        [_requestAry addObject:rpofileRe];
//        [rpofileRe connect];
//    } else {
//        [self delegateEngineRequestDidFailWithError:nil];
//    }
//}

- (void)requestUserProfile
{
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithDictionary:[self commonParams]];
    [params setObject:@"json" forKey:@"format"];
    [self loadRequestWithUrl:@"https://graph.qq.com/user/get_user_info"
                  httpMethod:@"GET"
                      params:params
                postDataType:kOFRequestPostDataTypeNone
            httpHeaderFields:nil];
}

- (void)uploadPicToQZone:(UIImage *)image
{
    if (image == nil) {
        return;
    }
    
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithDictionary:[self commonParams]];
    [params setObject:image forKey:@"picture"];
    
    [self loadRequestWithUrl:@"https://graph.qq.com/photo/upload_pic"
                  httpMethod:@"POST"
                      params:params
                postDataType:kOFRequestPostDataTypeMultipart
            httpHeaderFields:nil];
    
}

- (void)shareToQZoneWithTitle:(NSString *)title
                      comment:(NSString *)commentText
                     titleUrl:(NSString *)titleUrl
                      summary:(NSString *)summary
                        image:(UIImage *)image
{
    if (image == nil) {
        [self shareToQZoneWithTitle:title
                            comment:commentText
                           titleUrl:titleUrl
                            summary:summary
                           imageUrl:nil];
        return;
    }
    
    _shareTitle = [title retain];
    _shareComment = [commentText retain];
    _shareSummary = [summary retain];
    _linkURL = [titleUrl retain];
    
    [self uploadPicToQZone:image];
}

- (void)shareToQZoneWithTitle:(NSString *)title
                      comment:(NSString *)commentText
                     titleUrl:(NSString *)titleUrl
                      summary:(NSString *)summary
                     imageUrl:(NSString *)imageUrl
{
    if (title==nil || titleUrl==nil) {
        return;
    }
    
    //按要求截断字符串
    if (title.length>36) {
        title = [NSString stringWithFormat:@"%@⋯", [title substringToIndex:35] ];
    }
    
    NSMutableDictionary * params = [NSMutableDictionary dictionaryWithDictionary:[self commonParams]];
    [params setObject:title forKey:@"title"];
    [params setObject:titleUrl forKey:@"url"];
    
    if (commentText) {
        if (commentText.length>40) {
            commentText = [NSString stringWithFormat:@"%@⋯", [commentText substringToIndex:39] ];
        }
        
        [params setObject:commentText forKey:@"comment"];
        
    }
    
    if (summary) {
        if (summary.length>80) {
            summary = [NSString stringWithFormat:@"%@⋯", [summary substringToIndex:79] ];
        }
        [params setObject:summary forKey:@"summary"];
        
    }
    
    if (imageUrl) {
        if (imageUrl.length>255) {
            imageUrl = [NSString stringWithFormat:@"%@⋯", [imageUrl substringToIndex:254] ];
        }
        
        [params setObject:imageUrl forKey:@"images"];
    }
    
    [params setObject:[NSString stringWithFormat:@"1"] forKey:@"nswb"];
    
    [self loadRequestWithUrl:@"https://graph.qq.com/share/add_share"
                  httpMethod:@"POST"
                      params:params
                postDataType:kOFRequestPostDataTypeNormal
            httpHeaderFields:nil];
}


- (void)authorizeDidSuccee:(OFAuthorize *)authorize
{
    if (_openId == nil || [_openId isEqualToString:@""]) {
        return;
    }
    
    [super authorizeDidSuccee:authorize];
}

#pragma mark - OFRequestDelegate
- (void)request:(OFRequest *)request didFinishLoadingWithResult:(NSString *)result
{
    [self retain];
    if (request == _openIdRequset && result) {
        NSString *responseString = [result stringByReplacingOccurrencesOfString:@"callback" withString:@""];
        responseString = [responseString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"();\n"]];
        
        NSError *error = nil;
        NSDictionary * jsonDict = [self parseJSONString:responseString error:&error];
        if (jsonDict) {
            self.openId = [jsonDict objectForKey:@"openid"];
            [self authorizeDidSuccee:self.authorize];
        }else{
            [self authorize:self.authorize didFailWithError:nil];
        }
        
        [self release];
        return;
    }
    
    request.delegate = nil;
    [_requestAry removeObjectIdenticalTo:request];
    NSError * error = nil;
    NSDictionary * jsonDict = [self parseJSONString:result error:&error];
    BOOL failed = NO;
    if (!error) {
        if ([jsonDict isKindOfClass:[NSDictionary class]]) {
            id ret = [jsonDict objectForKey:@"ret"];
            if (ret && [ret isKindOfClass:[NSNumber class]] && [ret intValue] !=0 ) {
                failed = YES;
            }
        }
    } else {
        failed = YES;
    }
    
    if (failed) {
        [self delegateEngineRequestDidFailWithError:error];
    } else {
        NSArray  *array = [request.url componentsSeparatedByString:@"/"];
        NSString  *interface = (NSString *)[array lastObject];
        if ([interface isEqualToString:@"upload_pic"]) {
            NSString *smallURL = BUGetObjFromDict(@"small_url", jsonDict, [NSString class]);
            if (_imageUrl) {
                [_imageUrl release],_imageUrl = nil;
            }
            _imageUrl = [BUGetObjFromDict(@"large_url", jsonDict, [NSString class]) retain];
            
            [self shareToQZoneWithTitle:_shareTitle
                                comment:_shareComment
                               titleUrl:_linkURL
                                summary:_shareSummary
                               imageUrl:smallURL];
            
        }else{
            NSMutableDictionary   *dic = [NSMutableDictionary dictionaryWithCapacity:0];
            if ([jsonDict isKindOfClass:[NSDictionary class]]) {
                [dic addEntriesFromDictionary:(NSDictionary *)jsonDict];
            }
            
            if (_imageUrl && ![_imageUrl isEqualToString:@""]) {
                [dic setObject:_imageUrl forKey:@"large_url"];
            }
            [self delegateEngineRequestDidSucceedWithResult:dic];
        }
        
        if ([interface isEqualToString:@"add_share"]) {
            _shareTitle = nil;
            _shareComment = nil;
            _shareSummary = nil;
            _linkURL = nil;
            _imageUrl = nil;
        }
        
    }
    [self release];
}

@end
